package com.fhsk.file.business.common;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fhsk.file.common.exception.AuthenticationException;
import com.fhsk.file.common.utils.ReadYmlUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;

@Slf4j
public class JwtUtil {

    public static final Long EXPIRE_TIME = ReadYmlUtil.getLong("shiro.jwt.expireTime");

    /**
     * 校验token是否正确
     *
     * @param token  密钥
     * @param secret 用户的密码
     * @return 是否正确
     */
    public static boolean verify(String token, String username, String secret) {

        try {
            Algorithm algorithm = Algorithm.HMAC256(secret);
            JWTVerifier verifier = JWT.require(algorithm).withClaim("username", username).build();
            verifier.verify(token);
            return true;
        } catch (RuntimeException e) {
            throw new AuthenticationException(406, "您的登录已失效，请退出重新登录！");
        }
    }

    /**
     * 获得token中的信息无需secret解密也能获得
     *
     * @return token中包含的用户id
     */
    public static String getUserName(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("username").asString();
        } catch (RuntimeException e) {
            return null;
        }
    }

    /**
     * 生成签名
     *
     * @param username 用户用户名
     * @param secret   用户的密码
     * @return 加密的token
     */
    public static String sign(String username, String secret) {
        //默认7天时间
        long expireTime = 7 * 24 * 60 * 60 * 1000;

        if (EXPIRE_TIME != null) {
            expireTime = EXPIRE_TIME;
        } else {
            log.warn("配置文件读取token过期时间错误,请检查配置是否正确");
        }

        try {
            Date date = new Date(System.currentTimeMillis() + expireTime);
            Algorithm algorithm = Algorithm.HMAC256(secret);
            // 附带id信息
            return JWT.create().withClaim("username", username).withExpiresAt(date).sign(algorithm);
        } catch (RuntimeException e) {
            return null;
        }
    }

}
